#include "MainFrame.h"
#include <cvaux.h>
#include <cv.h>

#include "wxCamViewWindow.h"
#include "../nxColor.h"
#include <wx/tipwin.h>
#include "highgui.h"
#include "InfoDialog.h"
#include "DialogCoef.h"
#include <stdio.h>
#include <wx/string.h>
#include "DialogFilter.h"
#include "DialogFilterOrder.h"

#include "../ConfigFile.h"
#include "CalibParam.h"

#include <wx/intl.h>
#include <cassert>
#include <string> 
#include <list> 
#include <vector>
#include <dirent.h> 
#include <iostream>
#include "../Configuration/RobotProject.h"

using namespace std;


MainFrame::MainFrame( wxWindow* parent )
: 
MainFrameTemplate( parent )
{
 	wxLocale* x = new wxLocale(wxLANGUAGE_ENGLISH);
	this->toolBarApp->EnableTool(ID_PAUSE,false);
	this->toolBarApp->EnableTool(ID_ZOOMIN,false);
	this->toolBarApp->EnableTool(ID_ZOOMOUT,false);
	this->toolBarApp->EnableTool(ID_SAVE_IMG,false);
	this->toolBarApp->EnableTool(ID_CLASSDEF,false);
	
	//this->toolBarApp->EnableTool(ID_CLASSDEF,false);
	this->toolBarApp->EnableTool(ID_EXPAND,false);
	colorCode = HSV_CODE;
	camSource=-1; //No camera selected
	lowCoef= cvScalar(4,4,4);
	highCoef= cvScalar(4,4,4);
	colorListIndex = 0;
	process=false;
	comboBoxDefinedClasses->Append(wxT("All Colors"));

	thresholdDlg = new ThresholdDialog(this);
	areaDlg = new DialogMinMaxArea(this);
	distDlg = new DialogMinMaxDist(this);

	preSmoothParams[0]=3;
	preSmoothParams[1]=0;
	preSmoothParams[2]=0;
	
	posSmoothParams[0]=3;
	posSmoothParams[1]=0;
	posSmoothParams[2]=0;
	
	preErodeIterations=1;
	posErodeIterations=1;
	bckgndThresholds[0]=0;
	bckgndThresholds[1]=0;
	
	preSmoothType=CV_MEDIAN;
	posSmoothType=CV_MEDIAN;
	
	psPreFilter = true; 
	psPosFilter = true;
	psColorFilter = true;
	psColorId = true;
	
	minArea = 0;
	maxArea = MAX_COLOR_AREA;
	
	minDist = 0;
	maxDist = MAX_COLOR_DIST;
	
	robotProject = new RobotProject();
	
	robotFile = (char*)FILE_ROBOT;
	colorFile = (char*)FILE_COLOR;
	obstFile = (char*)FILE_OBST;
	projectFile = (char*)FILE_PROJECT;
	projectDir = new char[255];
	camURI = new char[255];
	
	sprintf(projectDir,"./");
	
	
} 

MainFrame::~MainFrame()
{
	delete thresholdDlg;
	delete areaDlg;

}
void MainFrame::assignCamWindow(wxCamViewWindow* camView)
{
	this->camView = camView;
	sizerCamera->Add( camView, 1, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL|wxEXPAND );
}
//Not Implemented 
void MainFrame::OnFrameSize( wxSizeEvent& event )
{
	sizerApp->Layout();
	sizerApp->RecalcSizes();
	sizerCamera->Layout();
	sizerCamera->RecalcSizes();
	sizerClassDef->Layout(); 
	sizerClassDef->RecalcSizes();
	//camView->updateImg();

}

void MainFrame::toolExpandClick( wxCommandEvent& event )
{
	camView->updateImg();
}

void MainFrame::OnMenuItemRemoteClick(wxCommandEvent& event)
{
	printf("seleccionada camara remota, por streaming\n");
}

void MainFrame::toolCamWindowClick( wxCommandEvent& event )
{
	wxMenuItem* local  = CameraMenu->FindItem(wxID_source_local);
	wxMenuItem* remote = CameraMenu->FindItem(wxID_source_remote);

	//sets the source for camera images. 0 for local cameras, 1 for remote (streaming) cameras
	if(local->IsChecked())
		camSource = 0;
	else
		camSource = 1;
	
	//sets the video interface (Ex: /dev/video0)or the URL to the streaming camera (Ex: localhost:8080/?action=snapshot)
	wxString m_camSrc;
	m_camSrc = textCtrlCameraSrc->GetValue();
	sprintf(camURI,"%s",(char*)m_camSrc.char_str());

	if(!this->camOn)
	{

		//define image size
		int imgWidth,imgHeight;

		wxMenuItem* res1024x768 = SizeMenu->FindItem(wxID_res_1024x768);
		wxMenuItem* res960x720 = SizeMenu->FindItem(wxID_res_960x720);
		wxMenuItem* res640x480 = SizeMenu->FindItem(wxID_res_640x480);
		wxMenuItem* res320x240 = SizeMenu->FindItem(wxID_res_320x240);

		if(res1024x768->IsChecked())
		{
			imgWidth = 1024;
			imgHeight = 768;
		}
		else if(res960x720->IsChecked())
		{
			imgWidth = 960;
			imgHeight = 720;
		}
		else if(res640x480->IsChecked())
		{
			imgWidth = 640;
			imgHeight = 480;
		}
		else
		{
			imgWidth = 320;
			imgHeight = 240;
		}


		//Camera off, proceed to initialize it

		//printf("%d\n",camSource);
		camView->initCam(camSource, camURI, imgWidth, imgHeight);
		this->toolBarApp->EnableTool(ID_PAUSE,true);
		this->toolBarApp->EnableTool(ID_SAVE_IMG,true);
		this->toolBarApp->EnableTool(ID_CLASSDEF,true);


		local->Enable(false);
		remote->Enable(false);

		areaDlg->setMaxVal(MAX_COLOR_AREA);
		distDlg->setMaxVal(MAX_COLOR_DIST);


		this->camOn=true;
	}
	else{

		defineClass=true;
		onMenuItemDefClassClick( event );
		OnMenuItemDefRobot( event );
		ColorMenu->Check(ID_COLORDEF,false);
		RobotMenu->Check(ID_ROBDEF,false);

		this->camOn=false;
		this->toolBarApp->EnableTool(ID_PAUSE,false);
		this->toolBarApp->EnableTool(ID_ZOOMIN,false);
		this->toolBarApp->EnableTool(ID_ZOOMOUT,false);
		this->toolBarApp->EnableTool(ID_EXPAND,false);
		this->toolBarApp->EnableTool(ID_SAVE_IMG,false);
		this->toolBarApp->EnableTool(ID_CLASSDEF,false);

		local->Enable(true);
		remote->Enable(true);
		camView->releaseCam();
		camView->setSelectEnable(false);
		camView->SetCursor(wxNullCursor);
		paused=false;


	}
}

void MainFrame::toolPauseClick( wxCommandEvent& event )
{
	if(!paused)
	{	
		camView->getCamImage();
		paused=true;
		this->toolBarApp->EnableTool(ID_ZOOMIN,true);
		this->toolBarApp->EnableTool(ID_ZOOMOUT,true);
		//this->toolBarApp->EnableTool(ID_CLASSDEF,true);	
		this->toolBarApp->EnableTool(ID_EXPAND,true);
		this->buttonCalculate->Enable(true);
		toolBarApp->SetToolNormalBitmap(ID_PAUSE, wxBitmap( wxT("img/toolbar/32x32/play.png"), wxBITMAP_TYPE_ANY ));
	}
	else
	{
		if(camView->isSelectEnable())
			toolZoomOutClick(event);
		paused=false;
		this->toolBarApp->EnableTool(ID_ZOOMIN,false);
		this->toolBarApp->EnableTool(ID_ZOOMOUT,false);
		//this->toolBarApp->EnableTool(ID_CLASSDEF,false);	
		this->toolBarApp->EnableTool(ID_EXPAND,false);
		this->buttonCalculate->Enable(false);
		toolBarApp->SetToolNormalBitmap(ID_PAUSE, wxBitmap( wxT("img/toolbar/32x32/pause.png"), wxBITMAP_TYPE_ANY ));
	}
	camView->setSelectEnable(false);
	camView->SetCursor(wxNullCursor);
}

void MainFrame::toolZommInClick( wxCommandEvent& event )
{
	//wxWindow::SetCursor
//virtual void SetCursor(const wxCursor&cursor)
	
	
	this->toolBarApp->EnableTool(ID_ZOOMIN,false);
	camView->SetCursor(*wxCROSS_CURSOR);
	camView->setSelectEnable(true);
} 

void MainFrame::toolZoomOutClick( wxCommandEvent& event )
{
	camView->setSelectEnable(false);
	this->toolBarApp->EnableTool(ID_ZOOMIN,true);
	camView->resetImg();
	camView->SetCursor(wxNullCursor);
}

void MainFrame::toolClassDefClick( wxCommandEvent& event )
{
	if(!process)
	{
		camView->loadCMVisionColors(colorList,colorListIndex);
		camView->setFilterOn(true);
		process=true;
		buttonEliminate->Enable(false);
		toolBarApp->SetToolNormalBitmap(ID_CLASSDEF, wxBitmap( wxT("img/toolbar/32x32/classOff.png"), wxBITMAP_TYPE_ANY ));
		
		//cvNamedWindow("My Window", 0);
		//cvNamedWindow("smooth", 0);
		//cvNamedWindow("no smooth", 0);
	}
	else
	{
		camView->setFilterOn(false);
		process=false;
		buttonEliminate->Enable(true);
		toolBarApp->SetToolNormalBitmap(ID_CLASSDEF, wxBitmap( wxT("img/toolbar/32x32/classOn.png"), wxBITMAP_TYPE_ANY ));
		
		//cvDestroyWindow("My Window");
		//cvDestroyWindow("smooth");
		//cvDestroyWindow("no smooth");
	}
	

				

	
}

void MainFrame::OnCalculateClick( wxCommandEvent& event )
{
	//get class name
	wxString name = textClassName->GetLineText(0);
	
	//If empty class name, show alert 
	if(!strcmp(name.char_str(),""))
	{
		
		if(infoDlg!=NULL)
			delete infoDlg;
			
		infoDlg = new InfoDialog(this,(wxString)wxT("ERROR!!!"),(wxString)wxT("The given color name "),(wxString)wxT("is not valid!"));
	}
	
	else
	{
		char* name_str= new char[30];;
		
		//conversion to char*
		sprintf(name_str,"%s",(char*)name.char_str());
		
		//Create color with the given name and array of pixels of the image captured in camView
		nxColor* color= new nxColor(name_str,camView->getCvImage(),RGB_CODE);
		
		//add pointer of color to color list
		if(colorListIndex != MAX_COLOR_CLASS)
		{
			//if(colorListIndex==0)
				//obstColor = color;
			colorList[colorListIndex++] = color;
			showColorInfo(color);
			
			//append color name to comboboxes	
			comboBoxDefinedClasses->Append(name.FromAscii(color->getName()));
			
			//Comboboxes for definition of robots
			comboboxBaseColor->Append(name.FromAscii(color->getName()));
			comboboxRobotColor->Append(name.FromAscii(color->getName()));
			
			//set defined color on combobox
			comboBoxDefinedClasses->SetSelection(comboBoxDefinedClasses->GetCount()-1);
			
			
			//update sliders on threshold dialog
			thresholdDlg->updateValues();			
		}
		
		
		else
		{
			cout<<"could not aggregate color to list!"<<endl;
			if(infoDlg!=NULL)
				delete infoDlg;
				
			infoDlg = new InfoDialog(this,(wxString)wxT("WARNING!!!"),(wxString)wxT("There is no space available"),(wxString)wxT("for created color!"));
			
			}	
		
		
		
		
		
	}
	
	
	
}

void MainFrame::OnDefinedClassesClick( wxCommandEvent& event )
{
	selectColor();
}

void MainFrame::selectColor()
{
	int index = comboBoxDefinedClasses->GetSelection()-1;
	
	if(index!=wxNOT_FOUND)
	{
		nxColor* color = colorList[index];
		showColorInfo(color);
		thresholdDlg->updateValues();
	}
	
}

void MainFrame::OnMenuItemExitClick( wxCommandEvent& event )
{
	Close();
	return;
}

void MainFrame::OnMenuItemHelpClick( wxCommandEvent& event )
{
	// TODO: Implement OnMenuItemHelpClick
}

void MainFrame::onMenuItemDefClassClick( wxCommandEvent& event )
{

	if(camOn)
	{
		if(event.IsChecked()) 
		{
			staticTextTitle->Show(true);
			panel1->Show(true);
			panel2->Show(true);
			panel3->Show(true);
			
			//panel4->Show(true);
			staticTextMVal->Show(true);
			staticTextSD->Show(true);
			textMVal0->Show(true);
			textMVal1->Show(true);
			textMVal2->Show(true);
			textSDVal0->Show(true);
			textSDVal1->Show(true);
			textSDVal2->Show(true);
			
			staticTextMCode0->Show(true);
			staticTextMCode1->Show(true);
			staticTextMCode2->Show(true);
			
			staticTextSDCode0->Show(true);
			staticTextSDCode1->Show(true);
			staticTextSDCode2->Show(true);
			
			buttonCalculate->Show(true);
			buttonEliminate->Show(true);
			
			staticTextClassName->Show(true);
			textClassName->Show(true);
			staticTextDefined->Show(true);
			comboBoxDefinedClasses->Show(true);
			defineClass=true;
		}
		else
		{
			staticTextTitle->Show(false);
			panel1->Show(false);
			panel2->Show(false);
			panel3->Show(false);
			//panel4->Show(false);
			
			staticTextMVal->Show(false);
			staticTextSD->Show(false);
			textMVal0->Show(false);
			textMVal1->Show(false);
			textMVal2->Show(false);
			textSDVal0->Show(false);
			textSDVal1->Show(false);
			textSDVal2->Show(false);
			
			staticTextMCode0->Show(false);
			staticTextMCode1->Show(false);
			staticTextMCode2->Show(false);
			
			staticTextSDCode0->Show(false);
			staticTextSDCode1->Show(false);
			staticTextSDCode2->Show(false);
			
			buttonCalculate->Show(false);
			buttonEliminate->Show(false);
			
			staticTextClassName->Show(false);
			textClassName->Show(false);
			staticTextDefined->Show(false);
			comboBoxDefinedClasses->Show(false);
			defineClass=false;
		}
		sizerApp->Layout();
		sizerClassDef->Layout();
		camView->updateImg();
	}
}

void MainFrame::OnMenuItemDefRobot( wxCommandEvent& event )
{
	if(camOn)
	{
		if(event.IsChecked())
		{
			staticTextTitleRobot->Show(true);
			panel11->Show(true);
			staticTextRobotName->Show(true);
			textCtrlRobotName->Show(true);
			staticTextBaseColor->Show(true); 
			comboboxBaseColor->Show(true);
			staticTextRobotColor->Show(true);
			comboboxRobotColor->Show(true);
			staticTextMinDist->Show(true);
			textCtrlMinDist->Show(true);
			staticTextMaxDist->Show(true);
			textCtrlMaxDist->Show(true);
			buttonCreateRobot->Show(true);
			m_staticline1->Show(true);
			staticTextDefinedRobots->Show(true);
			comboboxDefinedRobots->Show(true);
			buttonEliminateRobot->Show(true);
			
			
			
		}
		else
		{
			staticTextTitleRobot->Show(false);
			panel11->Show(false);
			staticTextRobotName->Show(false);
			textCtrlRobotName->Show(false);
			staticTextBaseColor->Show(false);
			comboboxBaseColor->Show(false);
			staticTextRobotColor->Show(false);
			comboboxRobotColor->Show(false);
			staticTextMinDist->Show(false);
			textCtrlMinDist->Show(false);
			staticTextMaxDist->Show(false);
			buttonCreateRobot->Show(false);
			m_staticline1->Show(false);
			textCtrlMaxDist->Show(false);
			staticTextDefinedRobots->Show(false);
			comboboxDefinedRobots->Show(false);
			buttonEliminateRobot->Show(false);
			
		}
		
		sizerApp->Layout(); 
		sizerRobotDef->Layout(); 
		camView->updateImg();
	}
}



void MainFrame::OnMenuRGBClick( wxCommandEvent& event )
{
	colorCode = RGB_CODE;
	staticTextMCode0->SetLabel((wxString)wxT("R"));
	staticTextMCode1->SetLabel((wxString)wxT("G"));
	staticTextMCode2->SetLabel((wxString)wxT("B"));
	
	staticTextSDCode0->SetLabel((wxString)wxT("R"));
	staticTextSDCode1->SetLabel((wxString)wxT("G"));
	staticTextSDCode2->SetLabel((wxString)wxT("B"));
	selectColor();
}

void MainFrame::OnMenuHLSClick( wxCommandEvent& event )
{
	colorCode = HLS_CODE;
	staticTextMCode0->SetLabel((wxString)wxT("H"));
	staticTextMCode1->SetLabel((wxString)wxT("L"));
	staticTextMCode2->SetLabel((wxString)wxT("S"));
	
	staticTextSDCode0->SetLabel((wxString)wxT("H"));
	staticTextSDCode1->SetLabel((wxString)wxT("L"));
	staticTextSDCode2->SetLabel((wxString)wxT("S"));
	
	selectColor();
}

void MainFrame::OnMenuHSVClick( wxCommandEvent& event )
{
	colorCode = HSV_CODE;
	staticTextMCode0->SetLabel((wxString)wxT("H"));
	staticTextMCode1->SetLabel((wxString)wxT("S"));
	staticTextMCode2->SetLabel((wxString)wxT("V"));
	
	staticTextSDCode0->SetLabel((wxString)wxT("H"));
	staticTextSDCode1->SetLabel((wxString)wxT("S"));
	staticTextSDCode2->SetLabel((wxString)wxT("V"));
	selectColor();
	
}

void MainFrame::OnMenuYUVClick( wxCommandEvent& event )
{
	colorCode = YUV_CODE;
	staticTextMCode0->SetLabel((wxString)wxT("Y"));
	staticTextMCode1->SetLabel((wxString)wxT("U"));
	staticTextMCode2->SetLabel((wxString)wxT("V"));

	staticTextSDCode0->SetLabel((wxString)wxT("Y"));
	staticTextSDCode1->SetLabel((wxString)wxT("U"));
	staticTextSDCode2->SetLabel((wxString)wxT("V"));
	selectColor();

	//CvScalar mean = getMeanValue(YUV_CODE);
	//CvScalar stdDev = getStdDev(YUV_CODE);

	//printf("Y:%d U:%d V:%d\n",mean.val[0],mean.val[1],mean.val[2]);
	//printf("Y:%d U:%d V:%d\n",stdDev.val[0],stdDev.val[1],stdDev.val[2]);


}

void MainFrame::OnMenuItemDefCoef( wxCommandEvent& event )
{
	//hay que cambiar esto, porq nunca se está eliminando este objeto
	//DialogCoef* x = new DialogCoef(this);
	
}

bool MainFrame::isCamOn()
{
	return this->camOn;
}

bool MainFrame::isPaused()
{
	return this->paused;
}

void MainFrame::setLowCoef(CvScalar lowCoef)
{
	this->lowCoef = lowCoef;
}

void MainFrame::setHighCoef(CvScalar highCoef)
{
	this->highCoef = highCoef;
}

CvScalar MainFrame::getLowCoef()
{
	return lowCoef;
	
}

CvScalar MainFrame::getHighCoef()
{
	return highCoef;
	
}

nxColor** MainFrame::getColorList()
{
	return colorList;
}

void MainFrame::showColorInfo(nxColor* color)
{
	CvScalar mean;
	CvScalar stdDev;
	
	//get mean and standard deviation of color class, based on the colorCode to be used
	switch(colorCode)
	{
		case RGB_CODE:
			mean =color->getMeanValue(RGB_CODE);
			stdDev = color->getStdDev(RGB_CODE);
		break;
		
		case HLS_CODE:
			mean =color->getMeanValue(HLS_CODE);
			stdDev = color->getStdDev(HLS_CODE);
		break;
		
		case HSV_CODE:
			mean =color->getMeanValue(HSV_CODE);
			stdDev = color->getStdDev(HSV_CODE);
			
		break;
		
		case YUV_CODE:
			mean =color->getMeanValue(YUV_CODE);
			stdDev = color->getStdDev(YUV_CODE);
		break;


	}
	
	char value[20];
	wxString wxValue;
	sprintf(value, "%f", mean.val[0]);
	
	wxValue = wxValue.FromAscii(value);
	textMVal0->SetValue(wxValue);
	
	sprintf(value, "%f", mean.val[1]);
	wxValue = wxValue.FromAscii(value);
	textMVal1->SetValue(wxValue);
	
	sprintf(value, "%f", mean.val[2]);
	wxValue = wxValue.FromAscii(value);
	textMVal2->SetValue(wxValue);
	
	
	sprintf(value, "%f", stdDev.val[0]);
	wxValue = wxValue.FromAscii(value);
	textSDVal0->SetValue(wxValue);
	
	sprintf(value, "%f", stdDev.val[1]);
	wxValue = wxValue.FromAscii(value);
	textSDVal1->SetValue(wxValue);
	
	sprintf(value, "%f", stdDev.val[2]);
	wxValue = wxValue.FromAscii(value);
	textSDVal2->SetValue(wxValue);
}

int MainFrame::getSelectedClass()
{
	return comboBoxDefinedClasses->GetSelection();
}

int MainFrame::getColorCode()
{
	return colorCode;
}

int MainFrame::getColorNumber()
{
	return colorListIndex;
}


void MainFrame::OnButtonEliminateColorClick( wxCommandEvent& event )
{
	int index = comboBoxDefinedClasses->GetSelection();
	
	if(index!=wxNOT_FOUND && index!=0)
	{
		
		//delete entry from combobox
		comboBoxDefinedClasses->Delete(index);
		comboboxBaseColor->Delete(index-1);
		comboboxRobotColor->Delete(index-1);

		
		//delete color instance from buffer
		nxColor* color =colorList[index-1];
		delete color;
		arrangeColorArray(index-1);
		
		//unselect combobox and delete text in fields
		comboBoxDefinedClasses->SetSelection(0);
		comboboxBaseColor->SetSelection(0);
		comboboxRobotColor->SetSelection(0);

		//TODO: Falta verificar que ningun robot tenga este color asignado,
		//si es asi, se debe eliminar tambien este robot.

		textMVal0->SetValue(wxT(""));
		textMVal1->SetValue(wxT(""));
		textMVal2->SetValue(wxT(""));
		
		textSDVal0->SetValue(wxT(""));
		textSDVal1->SetValue(wxT(""));
		textSDVal2->SetValue(wxT(""));
		
	}
}

void MainFrame::arrangeColorArray(int index)
{
	for(int i=0;i<colorListIndex;i++)
	{
		colorList[index+i]=colorList[index+i+1];
		colorList[index+i+1]= NULL;
	}
	colorListIndex--;
}


void MainFrame::setStatusBarText( wxString strText )
{

	GetStatusBar()->SetStatusText(strText);

}

void MainFrame::OnMenuItemColorIdent( wxCommandEvent& event )
{
	if(event.IsChecked())
		areaDlg->Show(true);
	else
		areaDlg->Show(false);
		
	areaDlg->updateAreas();
	
} 

void MainFrame::OnMenuItemDistDef( wxCommandEvent& event )
{
	if(event.IsChecked())
		distDlg->Show(true);
	else
		distDlg->Show(false);
		
	distDlg->updateDists();
}


void MainFrame::OnMenuItemProjectConfig( wxCommandEvent& event )
{
	// TODO: Implement OnMenuItemProjectConfig
}

void MainFrame::OnMenuItemPreFilter( wxCommandEvent& event )
{
	DialogFilter* df = new DialogFilter(this,0);
}

void MainFrame::OnMenuItemPosFilter( wxCommandEvent& event )
{
	DialogFilter* df = new DialogFilter(this,1);
}

void MainFrame::OnMenuItemFilterOrderClick( wxCommandEvent& event )
{
	DialogFilterOrder* dfo = new DialogFilterOrder(this);
}


void MainFrame::OnMenuItemPSPreFilter( wxCommandEvent& event )
{
	if(event.IsChecked())
		psPreFilter=true;
	else
		psPreFilter=false;
		
}


void MainFrame::OnMenuItemPSColorFilter( wxCommandEvent& event )
{
	if(event.IsChecked())
		psColorFilter=true;
	else
		psColorFilter=false;
		
		
}

void MainFrame::OnMenuItemPSColorId( wxCommandEvent& event )
{
	if(event.IsChecked())
		psColorId=true;
	else
		psColorId=false;
		
}

void MainFrame::OnMenuItemPSPosFilter( wxCommandEvent& event )
{
	if(event.IsChecked())
		psPosFilter=true;
	else
		psPosFilter=false;
		
}

void MainFrame::OnMenuItemSave( wxCommandEvent& event )
{
	char* temp = new char[255];
	sprintf(temp,"%s%s",projectDir,colorFile);
	camView->saveCMVisionConf(temp);
	//TODO: que aparezca ventana para elegir donde guardar
	//TODO: cambiar lo mostrado en la barra para que aparezca el verdadero nombre del archivo, tambien una alerta con un dialogo
	//setStatusBarText(wxT("Configuration saved as config.txt"));

	if(infoDlg!=NULL)
		delete infoDlg;
		//show dialog of success
		infoDlg = new InfoDialog(this,(wxString)wxT("SUCCESS!!!"),(wxString)wxT("Config. color file saved as"),(wxString)wxT("config.txt"));

	delete temp;
}


void MainFrame::OnMenuItemLoad( wxCommandEvent& event )
{
	cout<<"Entra"<<endl;
	//TODO: NO IMPOLEMENTADO TODAVIA revisar tambien qe el archivo ha sido abierto correctamente
	ConfigFile* file = new ConfigFile(projectFile,projectDir,true);
	
	file->readColorId();
	
	delete file;

}

void MainFrame::toolSaveClick( wxCommandEvent& event )
{
	static int index;
	IplImage* img = camView->getCvImage();
	cvCvtColor(img,img,CV_BGR2RGB);
	char *name = new char[20];
	sprintf(name,"calib-%i.png",index);
	
	cvSaveImage(name,img);
	delete name;
	index++;
}

void MainFrame::onMenuItemCalibParam( wxCommandEvent& event )
{
	CalibParam* x = new CalibParam(this);
}

void MainFrame::onMenuItemLoadCalib( wxCommandEvent& event )
{
	camView->setCalibParams();

}

void MainFrame::onMenuItemEnableCalib( wxCommandEvent& event )
{
	static bool enable= false;
	
	if(!enable){
		enable = true;
		camView->enableCalib(enable);		
	}
	else
	{
		enable = false;
		camView->enableCalib(enable);
	}
	
}
double* MainFrame::getEtalonParams()
{
	return camView->getEtalonParams();
}

void MainFrame::setEtalonParams(double *params)
{
	camView->setEtalonParams(params);
}

void MainFrame::OnMenuStartCalib( wxCommandEvent& event )
{
	camView->calibrateCam();
}

char* MainFrame::getImgDir()
{
	return camView->getImgDir();
}

void MainFrame::setImgDir(char* dir)
{
	camView->setImgDir(dir);
}
	
void MainFrame::OnMenuItemTH( wxCommandEvent& event )
{
	
	if(event.IsChecked())
		thresholdDlg->Show(true);
	
	else
		thresholdDlg->Show(false);
	
	
		thresholdDlg->updateValues();
	
		
}

void MainFrame::changeColorLUmbral(CvScalar lowUmbral)
{
	int index = comboBoxDefinedClasses->GetSelection();
	if(index>0)
	{
		nxColor *color = colorList[index-1];
		
		color->setLowUmbral(lowUmbral, colorCode);
		camView->loadCMVisionColors(colorList,colorListIndex);
	}

}

void MainFrame::changeColorHUmbral(CvScalar highUmbral)
{
	int index = comboBoxDefinedClasses->GetSelection();
	
	if(index>0)
	{
		
		nxColor *color = colorList[index-1];
	
		color->setHighUmbral(highUmbral, colorCode);
		camView->loadCMVisionColors(colorList,colorListIndex);
	}

}

CvScalar MainFrame::getColorLUmbral()
{
	int index = comboBoxDefinedClasses->GetSelection();
	
	if(index>0)
	{
		
		nxColor *color = colorList[index-1];
	
		return color->getLowUmbral(colorCode);
		
	}
	
	return cvScalarAll(0);
}

CvScalar MainFrame::getColorHUmbral()
{
	int index = comboBoxDefinedClasses->GetSelection();
	
	if(index>0)
	{
		nxColor *color = colorList[index-1];
	
		return color->getHighUmbral(colorCode);
		
	}
	
	return cvScalarAll(0);
}

void MainFrame::OnMenuItemSaveRobot( wxCommandEvent& event )
{

	//TODO: dar la opción de cambiar el nombre del archivo
	ConfigFile* file = new ConfigFile(robotFile,projectDir,false);
	ConfigFile* fileHomography = new ConfigFile("homography.txt",projectDir,false);

	//write player driver for camera
	if(camView->getCvImage()!=NULL)
	{
		file->writeDriverCamera(camSource,camView->getCvImage()->width,camView->getCvImage()->height);
		
		//write player driver for blobfinder
		file->writeDriverBlobfinder(colorFile);
		//write player driver for each defined robot 
		int numRobots = robotProject->getNumRobots();
		Robot** robArray = robotProject->getRobotArray();


		fileHomography->writePoints(camView->getImagePoints(), camView->getRealPoints());

		for(int i=0;i<numRobots;i++)
		{
			if(camView->isProyectPlaneReady())
			{

				if(camView->getDistParams()!=NULL)
				{
					if(camView->getIntrinsicParams()!=NULL)
						file->writeDriverRobotPos(robArray[i],i,camView->getMatrixProyArray(),camView->getDistParams(),camView->getIntrinsicParams());
					else
						file->writeDriverRobotPos(robArray[i],i,camView->getMatrixProyArray(),camView->getDistParams(),NULL);

				}
				else
				{
					if(camView->getIntrinsicParams()!=NULL)
						file->writeDriverRobotPos(robArray[i],i,camView->getMatrixProyArray(),NULL,camView->getIntrinsicParams());
					else
						file->writeDriverRobotPos(robArray[i],i,camView->getMatrixProyArray(),NULL,NULL);
				}

			}
			else
			{
				if(camView->getDistParams()!=NULL)
				{
					if(camView->getIntrinsicParams()!=NULL)

						file->writeDriverRobotPos(robArray[i],i,NULL,camView->getDistParams(),camView->getIntrinsicParams());
					else
						file->writeDriverRobotPos(robArray[i],i,NULL,camView->getDistParams(),NULL);
				}
				else
				{
					if(camView->getIntrinsicParams()!=NULL)
						file->writeDriverRobotPos(robArray[i],i,NULL,NULL,camView->getIntrinsicParams());
					else
						file->writeDriverRobotPos(robArray[i],i,NULL,NULL,NULL);
				}

			}
			
		}
		
		if(infoDlg!=NULL)
			delete infoDlg;
		//show dialog of success
		infoDlg = new InfoDialog(this,(wxString)wxT("SUCCESS!!!"),(wxString)wxT("Driver File saved as"),wxString::FromAscii(robotFile));
	
	}
	else
	{
		if(infoDlg!=NULL)
			delete infoDlg;
		infoDlg = new InfoDialog(this,(wxString)wxT("WARNING!!!"),(wxString)wxT("No camera was initialized!"),(wxString)wxT(""));
	}
	
	//file->writeAreas(minArea,maxArea);
	//file->writeRobots(robotProject);
	delete file;	
}

void MainFrame::OnButtonEliminateRobotClick( wxCommandEvent& event )
{
	//get index of robot to be eliminated
	int index = comboboxDefinedRobots->GetSelection();
	
	
	if(index!=wxNOT_FOUND)
	{
		//delete entry from comboBox
		comboboxDefinedRobots->Delete(index);
		
		//delete robot from project
		robotProject->removeRobot(index);
		
		//unselect combobox and delete text in fields
		comboboxDefinedRobots->SetSelection(wxNOT_FOUND);
		comboboxDefinedRobots->SetValue(wxT(""));
		
		
	}

}

void MainFrame::OnButtonCreateRobotClick( wxCommandEvent& event )
{
	wxString name = textCtrlRobotName->GetLineText(0);
	wxString minDist = textCtrlMinDist->GetLineText(0);
	wxString maxDist = textCtrlMaxDist->GetLineText(0);
	
	if(infoDlg!=NULL)
		delete infoDlg;
	//If is empty name, minDist or maxDist, show alert 
	if(!strcmp(name.char_str(),"") || !strcmp(minDist.char_str(),"") || !strcmp(maxDist.char_str(),""))
		infoDlg = new InfoDialog(this,(wxString)wxT("ERROR!!!"),(wxString)wxT("The given robot name, minDist or maxDist"),(wxString)wxT("is not valid!"));
	else
	{
		//check if there is space available for the robot
		if(robotProject->getNumRobots() == MAX_ROBOTS)
		{
			infoDlg = new InfoDialog(this,(wxString)wxT("WARNING!!!"),(wxString)wxT("There is no space available"),(wxString)wxT("for created robot!"));
			return;
		}
		int selectedBaseColor = comboboxBaseColor->GetSelection();
		int selectedRobotColor = comboboxRobotColor->GetSelection();
		
		//if there is no selection of the colors for robot, alert the user
		if(selectedBaseColor==-1 || selectedRobotColor==-1 || selectedBaseColor == selectedRobotColor)
			//TODO: muchas llamadas a new para infoDlg, en ningun lado se estan eliminando
			infoDlg = new InfoDialog(this,(wxString)wxT("WARNING!!!"),(wxString)wxT("Either one of the colors is not selected,"),(wxString)wxT("or both are equal!!"));
		
		//recover colors for robot
		nxColor* baseColor = colorList[selectedBaseColor];
		nxColor* robotColor = colorList[selectedRobotColor];
		
		//name of robot
		char* name_str= new char[30];
		sprintf(name_str,"%s",(char*)name.char_str());
			
		//create robot
		Robot* robot = new Robot(name_str,baseColor,robotColor);
		
		//define min dist and max dist
		robot->setMinDist(this->minDist);
		robot->setMaxDist(this->maxDist);
		
		//define min and max area
		robot->setMinArea(this->minArea);
		robot->setMaxArea(this->maxArea);
		
		
		robotProject->appendRobot(robot);
		
		//add robot to list and select last item
		comboboxDefinedRobots->Append(name);
		comboboxDefinedRobots->SetSelection(comboboxDefinedRobots->GetCount()-1);
	}
	
}

void MainFrame::OnToolArea( wxCommandEvent& event )
{
	static bool state = true;
	if(state)
	{
		camView->SetCursor(*wxCROSS_CURSOR);
		camView->traceAxes(true);
		state = false;
	}
	else
	{
		camView->SetCursor(wxNullCursor);
		camView->traceAxes(false);
		state = true;
		
	}
	
}
 
void MainFrame::OnTextCtrlCommandEnter( wxCommandEvent& event )
{
	//TODO:
}


void MainFrame::setMaxArea(int maxArea){
	this->maxArea = maxArea;
	
	//update area in robots
	int numRobots = robotProject->getNumRobots();
	Robot** robArray = robotProject->getRobotArray();
	for(int i=0;i<numRobots;i++)
	{
		robArray[i]->setMaxArea(maxArea);
	}
}

void MainFrame::setMinArea(int minArea){
	
	this->minArea = minArea;
	//update area in robots
	int numRobots = robotProject->getNumRobots();
	Robot** robArray = robotProject->getRobotArray();
	for(int i=0;i<numRobots;i++)
	{
		robArray[i]->setMinArea(minArea);
	}
		
}

void MainFrame::setMaxDist(int maxDist){
	
	//update area in robots
	int numRobots = robotProject->getNumRobots();
	Robot** robArray = robotProject->getRobotArray();
	for(int i=0;i<numRobots;i++)
	{
		robArray[i]->setMaxDist(maxDist);
	}
}

void MainFrame::setMinDist(int minDist){

	//update area in robots
	int numRobots = robotProject->getNumRobots();
	Robot** robArray = robotProject->getRobotArray();
	for(int i=0;i<numRobots;i++)
	{
		robArray[i]->setMinDist(minDist);
	}
		
}


void MainFrame::onMenuItemSaveObst( wxCommandEvent& event )
{
	
	//TODO: dar la opción de cambiar el nombre del archivo
	
	ConfigFile* file = new ConfigFile(obstFile,projectDir,false);


	if(obstColor!=NULL)
	{
		printf("obstcolor no es null!\n");
			if(camView->isProyectPlaneReady() && camView->getDistParams()!=NULL && camView->getIntrinsicParams()!=NULL)
				file->writeObstConfig(obstColor,camView->getMatrixProyArray(),camView->getDistParams(),camView->getIntrinsicParams(),minArea,maxArea);
	
			else
				file->writeObstConfig(obstColor,NULL,NULL,NULL,minArea,maxArea);

			if(infoDlg!=NULL)
				delete infoDlg;
		
		//show dialog of success
		infoDlg = new InfoDialog(this,(wxString)wxT("SUCCESS!!!"),(wxString)wxT("Config File saved as"),wxString::FromAscii(obstFile));
	}
	else
		infoDlg = new InfoDialog(this,(wxString)wxT("ERROR!!!"),(wxString)wxT("No color for"),(wxString)wxT("Obstacles assigned"));

	
	//file->writeAreas(minArea,maxArea);
	//file->writeRobots(robotProject);
	delete file;	
}

void MainFrame::OnMenuItemObstColor( wxCommandEvent& event )
{
	int index = comboBoxDefinedClasses->GetSelection();
	if(index>0)
	{
		obstColor = colorList[index-1];
	}
}

void MainFrame::OnMenuitemProjectDirClic( wxCommandEvent& event )
{
	wxDirDialog* x = new wxDirDialog(this);
	int status = x->ShowModal();
	
	if(status ==wxID_OK){
		wxString a = x->GetPath();
		
		//save directory path in projectdir variable
		sprintf(projectDir,"%s/",(char*)a.char_str());
		
	}
	
	delete x;
	x = NULL;
	
} 

void MainFrame::onMenuItemSaveAll( wxCommandEvent& event )
{
	onMenuItemSaveObst(event);
	OnMenuItemSaveRobot(event);
	OnMenuItemSave(event);
	ConfigFile* file = new ConfigFile(projectFile,projectDir,false);
	file->writeColors(this->colorList,this->colorListIndex);
	delete file;
	
	
}
